Wilson@思源

目 录

监听思源main websocket

js
// see https://github.com/siyuan-note/siyuan/blob/1710194122495d282a51650441d9fc80804561bb/app/src/layout/Model.ts // see https://github.com/siyuan-note/siyuan/blob/1710194122495d282a51650441d9fc80804561bb/kernel/util/websocket.go (() => { // 创建socket客户端 createSocketClient(siyuan.ws.ws.url); // 当收到消息时被调用 function onReceivedMessage(event) { const message = parseJson(event.data); if(message.cmd === 'transactions') { // 这里获取更新后的数据 console.log(message); } } // 创建socket客户端 function createSocketClient(url) { // 连接 WebSocket 服务器 const socket = new WebSocket(url); socket.onopen = function(event) { console.log('WebSocket opened'); }; socket.onmessage = onReceivedMessage; socket.onclose = function(event) { console.log('WebSocket closed!'); }; socket.onerror = function(error) { console.error('WebSocket Error:', error); }; return socket; } // 客户端向服务器发送消息 function sendMessage(socket, message) { if (socket.readyState === WebSocket.OPEN) { socket.send(message); } else { console.error('WebSocket connection is not open'); } } // 解析json function parseJson(jsonString) { let json = {}; try { json = JSON.parse(jsonString || '{}'); } catch(e) { json = {}; console.error('parseJson error', e); } return json; } })()
see https://github.com/siyuan-note/siyuan/issues/13313?utm_source=ld246.com#issuecomment-2513905906
测试结果
测试代码
js
// see https://github.com/siyuan-note/siyuan/blob/1710194122495d282a51650441d9fc80804561bb/app/src/layout/Model.ts // see https://github.com/siyuan-note/siyuan/blob/1710194122495d282a51650441d9fc80804561bb/kernel/util/websocket.go (() => { // 创建socket客户端 createSocketClient(siyuan.ws.ws.url); let time = 0, blockId = ''; // 记录刚刚输入完数据 document.body.addEventListener('keyup', async (event) => { time = new Date().getTime(); // 更新前 blockId = event.target.lastElementChild?.dataset?.nodeId; const result = await fetchSyncPost('/api/block/getBlockDOM', {id: blockId}); console.log('before transactions', result.data?.dom); }) // 当收到消息时被调用 async function onReceivedMessage(event) { const message = parseJson(event.data); if(message.cmd === 'transactions') { // 这里获取更新后的数据 console.log(new Date().getTime() - time, message); // 更新后 const result = await fetchSyncPost('/api/block/getBlockDOM', {id: blockId}); console.log('after transactions', result.data?.dom); } } // 创建socket客户端 function createSocketClient(url) { // 连接 WebSocket 服务器 const socket = new WebSocket(url); socket.onopen = function(event) { console.log('WebSocket opened'); }; socket.onmessage = onReceivedMessage; socket.onclose = function(event) { console.log('WebSocket closed!'); }; socket.onerror = function(error) { console.error('WebSocket Error:', error); }; return socket; } // 客户端向服务器发送消息 function sendMessage(socket, message) { if (socket.readyState === WebSocket.OPEN) { socket.send(message); } else { console.error('WebSocket connection is not open'); } } // 解析json function parseJson(jsonString) { let json = {}; try { json = JSON.parse(jsonString || '{}'); } catch(e) { json = {}; console.error('parseJson error', e); } return json; } // 发送api请求 async function fetchSyncPost(url, data, returnType = 'json') { const init = { method: "POST", }; if (data) { if (data instanceof FormData) { init.body = data; } else { init.body = JSON.stringify(data); } } try { const res = await fetch(url, init); const res2 = returnType === 'json' ? await res.json() : await res.text(); return res2; } catch(e) { console.log(e); return returnType === 'json' ? {code:e.code||1, msg: e.message||"", data: null} : ""; } } })()
直接监听方法
不用再次启动客户端监听了,只需要监听思源已有的客户端的消息事件即可
js
siyuan.ws.ws.addEventListener('message', (e) => { const msg = JSON.parse(e.data); if(msg.cmd === "transactions") { // 这里获取更新后的数据 console.log(msg); } });
终极方案。
封装成了仅调用一次的便捷方案。
如果持续监听用原生更方便。
js
// 当块被保存时执行回调(仅执行一次) function whenBlockSaved(filter) { return new Promise((resolve, reject) => { const ws = siyuan.ws.ws; const clearEvent = () => ws.removeEventListener('message', handler); const handler = (event) => { try { const msg = JSON.parse(event.data); if(msg.cmd === "transactions") { if(typeof filter === 'function') { if(filter(msg)) resolve(msg); } else { resolve(msg); } clearEvent(); } } catch(e) { reject(e); clearEvent(); } } clearEvent(); ws.addEventListener('message', handler); }); } // 调用示例 // 链式调用 // whenBlockSaved().then((msg) => { // console.log(msg); // }); // 异步调用 // const msg = await whenBlockSaved(); // console.log(msg); // 过滤条件 // whenBlockSaved(msg => { // return msg.data.find(item => item.doOperations.find(item2 => item2.action === 'update' && item2.id === '20241204115642-hmpp8kh')); // }).then((msg) => { // console.log(msg); // }); // const filter = msg => msg.data.find(item => item.doOperations.find(item2 => item2.action === 'update' && item2.id === '20241204115642-hmpp8kh')); // const msg = await whenBlockSaved(filter); // console.log(msg);